package com.dcits.business.server.tomcat.jmx;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.dcits.business.server.tomcat.TomcatExtraParameter;
import com.dcits.business.server.tomcat.TomcatMonitoringInfo;
import com.dcits.business.server.tomcat.TomcatServer;
import com.dcits.tool.RmpUtil;
import com.dcits.tool.StringUtils;


public class JMXTomcatUtil {
	
	private static final Logger logger = Logger.getLogger(JMXTomcatUtil.class);
	
	public static void getJMXConnection(TomcatServer tomcat) throws IOException {
		String jmxUrl = "service:jmx:rmi:///jndi/rmi://" + tomcat.getHost() + ":" + tomcat.getPort() + "/jmxrmi";
		
		JMXServiceURL serviceURL = new JMXServiceURL(jmxUrl); 
		
		JMXConnector connector = null;
		if (StringUtils.isEmpty(tomcat.getUsername()) && StringUtils.isEmpty(tomcat.getPassword())) {
			connector = JMXConnectorFactory.connect(serviceURL);
		} else {			
			Map map = new HashMap();  
            String[] credentials = new String[] {tomcat.getUsername(), tomcat.getPassword()};  
            map.put("jmx.remote.credentials", credentials); 
            connector = JMXConnectorFactory.connect(serviceURL, map);
		}
		
		MBeanServerConnection mbsc = connector.getMBeanServerConnection(); 
		tomcat.setMbsc(mbsc);
	}
	
	public static void getMonitoringInfo(TomcatServer tomcat) {
		TomcatMonitoringInfo monitoringInfo = (TomcatMonitoringInfo) tomcat.getInfo();
		
		try {
			//获取基本信息
			ObjectName runtimeObjName = new ObjectName("java.lang:type=Runtime"); 
			
			Date starttime = new Date((Long) tomcat.getMbsc().getAttribute(runtimeObjName, "StartTime")); 
			monitoringInfo.setStartTime(RmpUtil.formatDate(starttime, "yyyy-MM-dd HH:mm:ss"));
			
			Long timespan = (Long) tomcat.getMbsc().getAttribute(runtimeObjName, "Uptime"); 
			monitoringInfo.setUpTime(RmpUtil.formatTimeSpan(timespan));
			
			//获取附加参数
			int webPort = 8080;
			String projectName = "/";
			if (StringUtils.isNotEmpty(tomcat.getParameters())) {
				TomcatExtraParameter parameter = JSONObject.parseObject(tomcat.getParameters(), new TypeReference<TomcatExtraParameter>(){});
				if (StringUtils.isNotEmpty(parameter.getProjectName())) projectName =  parameter.getProjectName();
				if (parameter.getWebPort() != null)  webPort = parameter.getWebPort();
			}
			
			monitoringInfo.setWebPort(webPort);
			monitoringInfo.setProjectPath(projectName);
			
			//获取session信息
			ObjectName managerObjName = new ObjectName("Catalina:type=Manager,context=" + projectName + ",*");
			List<ObjectName> s = new ArrayList<ObjectName>(tomcat.getMbsc().queryNames(managerObjName, null));
			ObjectName objname = new ObjectName(s.get(0).getCanonicalName());
			monitoringInfo.setSessionActiveCount(RmpUtil.getAttribute(objname, "activeSessions", tomcat.getMbsc()).toString());
			monitoringInfo.setSessionMaxActiveCount(RmpUtil.getAttribute(objname, "maxActiveSessions", tomcat.getMbsc()).toString());
			monitoringInfo.setSessionCounter(RmpUtil.getAttribute(objname, "sessionCounter", tomcat.getMbsc()).toString());
			
			
			//获取thread信息
			ObjectName threadpoolObjName = new ObjectName("Catalina:type=ThreadPool,name=\"http-*-" + webPort + "\""); 
			List<ObjectName> t = new ArrayList<ObjectName>(tomcat.getMbsc().queryNames(threadpoolObjName, null));
			objname = new ObjectName(t.get(0).getCanonicalName());
			
			String name = t.get(0).getKeyProperty("name");
			monitoringInfo.setRunType(name.split("-")[1]);
			
			monitoringInfo.setThreadMaxCount(RmpUtil.getAttribute(objname, "maxThreads", tomcat.getMbsc()).toString());
			monitoringInfo.setThreadCurrentCount(RmpUtil.getAttribute(objname, "currentThreadCount", tomcat.getMbsc()).toString());
			monitoringInfo.setThreadCurrentBusyCount(RmpUtil.getAttribute(objname, "currentThreadsBusy", tomcat.getMbsc()).toString());
						
			tomcat.setConnectStatus("true");
			monitoringInfo.setTime(new Date());
		} catch (Exception e) {
			// TODO: handle exception
			logger.error("获取tomcat信息出错", e);
			tomcat.setConnectStatus("获取tomcat信息出错：" + e.getMessage() == null ? "未知错误!" : e.getMessage());
		}
		
	}
}
